using System;
using System.Collections.Generic;

namespace MVP.ValueObject
{
    public sealed class Country : IEquatable<Country>
    {
        public static readonly Country ARGENTINA = new Country("Argentina");
        public static readonly Country AUSTRIA = new Country("Austria");
        public static readonly Country BELGIUM = new Country("Belgium");
        public static readonly Country BRAZIL = new Country("Brazil");
        public static readonly Country DENMARK = new Country("Denmark");
        public static readonly Country FINLAND = new Country("Finland");
        public static readonly Country FRANCE = new Country("France");
        public static readonly Country GERMANY = new Country("Germany");
        public static readonly Country IRELAND = new Country("Ireland");
        public static readonly Country ITALY = new Country("Italy");
        public static readonly Country MEXICO = new Country("Mexico");
        public static readonly Country NORWAY = new Country("Norway");
        public static readonly Country POLAND = new Country("Poland");
        public static readonly Country PORTUGAL = new Country("Portugal");
        public static readonly Country SPAIN = new Country("Spain");
        public static readonly Country SWEDEN = new Country("Sweden");
        public static readonly Country SWITZERLAND = new Country("Switzerland");
        public static readonly Country UK = new Country("UK");
        public static readonly Country VENEZUELA = new Country("Venezuela");
        public static readonly Country CANADA = new Country("Canada");
        public static readonly Country USA = new Country("USA");
        public static readonly Country NON_EXISTANT = new Country("Unknown");


        private static IDictionary<string, Country> ALL_COUNTRIES;

        private readonly string name;

        static Country()
        {
            ALL_COUNTRIES = new Dictionary<string, Country>();
            ALL_COUNTRIES.Add(ARGENTINA.Name, ARGENTINA);
            ALL_COUNTRIES.Add(AUSTRIA.Name, AUSTRIA);
            ALL_COUNTRIES.Add(BELGIUM.Name, BELGIUM);
            ALL_COUNTRIES.Add(BRAZIL.Name, BRAZIL);
            ALL_COUNTRIES.Add(CANADA.Name, CANADA);
            ALL_COUNTRIES.Add(DENMARK.Name, DENMARK);
            ALL_COUNTRIES.Add(FINLAND.Name, FINLAND);
            ALL_COUNTRIES.Add(FRANCE.Name, FRANCE);
            ALL_COUNTRIES.Add(GERMANY.Name, GERMANY);
            ALL_COUNTRIES.Add(IRELAND.Name, IRELAND);
            ALL_COUNTRIES.Add(ITALY.Name, ITALY);
            ALL_COUNTRIES.Add(MEXICO.Name, MEXICO);
            ALL_COUNTRIES.Add(NORWAY.Name, NORWAY);
            ALL_COUNTRIES.Add(POLAND.Name, POLAND);
            ALL_COUNTRIES.Add(PORTUGAL.Name, PORTUGAL);
            ALL_COUNTRIES.Add(SPAIN.Name, SPAIN);
            ALL_COUNTRIES.Add(SWEDEN.Name, SWEDEN);
            ALL_COUNTRIES.Add(SWITZERLAND.Name, SWITZERLAND);
            ALL_COUNTRIES.Add(UK.Name, UK);
            ALL_COUNTRIES.Add(USA.Name, USA);
            ALL_COUNTRIES.Add(VENEZUELA.Name, VENEZUELA);
        }


        private Country(string name)
        {
            this.name = name;
        }

        public static Country FindByName(string name)
        {
            try
            {
                return ALL_COUNTRIES[name];
            }
            catch (KeyNotFoundException)
            {
                return NON_EXISTANT;
            }
        }

        public string Name
        {
            get { return this.name; }
        }


        public override int GetHashCode()
        {
            return name.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as Country);
        }

        public bool Equals(Country other)
        {
            return (other == null ? false : IsEqualTo(other));
        }

        private bool IsEqualTo(Country other)
        {
            return other == this || this.Name.Equals(other.Name);
        }
    }
}